Using the console vs. Scripts vs. Markdown vs. R Notebooks

Welcome to using R. This subsection will explain the basics about R. First, lets discuss the different ways to write R code, as there are (at least) 5:

The Console

At the bottom left of RStudio you should have a console that looks something like what’s highlighted in red below:

You can type straight into the console, to get a result. You can scroll through your previous commands by pressing the up arrow in the console. Each time code is run in the console it updates the environment in the top right of R-Studio:

Scripts

The word “script” can be interpreted specifically, to refer to a type of R file that includes a lot of code, or generally to refer to any file that includes both R code and code that allows you make a nice looking report. In this subsection, we will be focusing on “script” as a particular type of file. To create a script, click on File -> New File -> R Script

You will then be shown a blank script, in which you can write a series of functions, and then run them. To run the lines of code, select a line, and then press CTRL-ENTER, or highlight a chunk of code and then press CTRL-ENTER. In either case, the code will be sent to the console and run there.

An advantage of a script over just using the console is that you can analyse your data in both structured and complex ways which is difficult if you are typing code directly into the console.

R Markdown

As highlighted above, R Markdown is a type of “script” in the general sense of the word, but allows you to create beautiful .html notebooks (.html files are what internet pages are based on). You are in fact reading an example of what can be produced by R Markdown (and R Notebooks). To make an R Markdown file, click on File -> New File -> R Markdown. You will be asked for a title, author and what output you would like. I would suggest “first markdown”, your name and “html” as the respective answers. You should then see something like:

The following points apply to both R Markdown and R Notebooks

If you look above, you may notice that there are 2 types of code: Markdown (to write a nice looking report) and R (in grey chunks). I think these are well explained here: https://www.rstudio.com/wp-content/uploads/2015/02/rmarkdown-cheatsheet.pdf so I’ll just explain that R Markdowns run all the code in the chunks each time they generate the output file (e.g. html file). This is important to know, because R Notebooks do not do this.

R Notebooks

R Notebooks can be created by clicking on File -> New File -> R Notebook. They look quite similar to R Markdowns, but automatically generate the .html output each time you save the notebook. The output file will be a .nb.html file in the same folder as your notebook.

Very importantly - the .nb.html file will be built based on what happened the last time you run each R chunk. If you never ran the R Chunk, then the nb.html file will not use the output from that chunk. This makes R Notebooks quicker than R Markdowns, because you don’t have to generate the output from scratch each time, but there is a risk of you forgetting to run a chunk after changing it.

Fundamental’s of R

R allows you to complete calculations, so lets start with that. Type into your markdown or script

Often, you can use R as a calculator, for example:

5 + 2
[1] 7

It’s helpful to store these calculations into objects:

a <- 5 + 2  # this is exactly the same as writing a = 5 + 2, but <- is encouraged in R to avoid confusion with other uses of = (e.g. == operator when you are comparing if two values are identical)
# this # is starting a comment, code that will be ignored but allows you to annotate your work
a # to show what the value 5 is now stored in the object "a"
[1] 7

This means that you can compare objects to each other later

b <- 2
b - a
[1] -5
c <- b-a
c # to show what c is
[1] -5

Some advice/rules for Objects:

this_object <- 5
this_object # to show what the object value is
[1] 5
this_object <- 10 # overwrites this_object
this_object # should now show 10
[1] 10

Functions

In a variety of coding languages like R, functions are lines of code you can apply each time you call the function, and apply it to input to get an output. If you wanted to make a function that multiplied numbers by 2, it would look something like:

times_two <- function(input){  # Define your function by stating it's name, and then using <- to describe it
  output = input * 2           # creates an output object that is the input object (see line above) x 2
  return (output)              # gives the output back to the user when they run the function
}
times_two(4)                   # should give you 8
[1] 8

The great news is that you don’t need to write functions 99% of the time in R, there are a wide variety of functions that are available. Some of which will be used in the next section.

Types of Objects

Vectors

Vectors store a series of values. Often these will be a series of numbers:

numeric_vector = c(1,2,3)
numeric_vector
[1] 1 2 3

The “c” above is short for “combine” as you’re combining values together to make this vector. Strings are values that have characters (also known as letters) in them. Lets see if we can make a vector of strings:

string_vector = c("a", "b", "c")
string_vector
[1] "a" "b" "c"

Looks like we can. But what happens if you mix strings and numbers in a vector:

mixed_vector = c("a", 1, "c")
mixed_vector
[1] "a" "1" "c"

R seems to be happy to put them into a single vector. But there are different types of values and vectors, so lets ask R what each type of (using the “typeof” function) vectors we have above:

typeof(numeric_vector)
[1] "double"
typeof(string_vector)
[1] "character"
typeof(mixed_vector)
[1] "character"

The numeric vector is a “double” vector. Double refers to the fact that the numbers can include decimals, as opposed to integer numbers which have to be whole numbers. Interestingly, R has assumed the list of numbers should be double rather than integer, which seems like the more robust thing to do, as integer numbers can always be double, but double numbers can’t always be integers.

Data frames

Data frames look like tables, in which you have a series of columns with headers that describe each column.

Some data frames are already loaded into RStudio when you run it, such as the “mpg” dataframe. To look at it, just type in it’s name:

mpg

Note that you may see 2 tables above, but they should be identical if so

The mpg dataframe has information about a variety of cars, their manufacturers, models, as described https://ggplot2.tidyverse.org/reference/mpg.html. You will need to refer to data frames and their columns, the convention for this being to write data frame$column. Lets do this to see what’s in the “manufacturer” column:

mpg$manufacturer
  [1] "audi"       "audi"       "audi"       "audi"       "audi"       "audi"       "audi"       "audi"      
  [9] "audi"       "audi"       "audi"       "audi"       "audi"       "audi"       "audi"       "audi"      
 [17] "audi"       "audi"       "chevrolet"  "chevrolet"  "chevrolet"  "chevrolet"  "chevrolet"  "chevrolet" 
 [25] "chevrolet"  "chevrolet"  "chevrolet"  "chevrolet"  "chevrolet"  "chevrolet"  "chevrolet"  "chevrolet" 
 [33] "chevrolet"  "chevrolet"  "chevrolet"  "chevrolet"  "chevrolet"  "dodge"      "dodge"      "dodge"     
 [41] "dodge"      "dodge"      "dodge"      "dodge"      "dodge"      "dodge"      "dodge"      "dodge"     
 [49] "dodge"      "dodge"      "dodge"      "dodge"      "dodge"      "dodge"      "dodge"      "dodge"     
 [57] "dodge"      "dodge"      "dodge"      "dodge"      "dodge"      "dodge"      "dodge"      "dodge"     
 [65] "dodge"      "dodge"      "dodge"      "dodge"      "dodge"      "dodge"      "dodge"      "dodge"     
 [73] "dodge"      "dodge"      "ford"       "ford"       "ford"       "ford"       "ford"       "ford"      
 [81] "ford"       "ford"       "ford"       "ford"       "ford"       "ford"       "ford"       "ford"      
 [89] "ford"       "ford"       "ford"       "ford"       "ford"       "ford"       "ford"       "ford"      
 [97] "ford"       "ford"       "ford"       "honda"      "honda"      "honda"      "honda"      "honda"     
[105] "honda"      "honda"      "honda"      "honda"      "hyundai"    "hyundai"    "hyundai"    "hyundai"   
[113] "hyundai"    "hyundai"    "hyundai"    "hyundai"    "hyundai"    "hyundai"    "hyundai"    "hyundai"   
[121] "hyundai"    "hyundai"    "jeep"       "jeep"       "jeep"       "jeep"       "jeep"       "jeep"      
[129] "jeep"       "jeep"       "land rover" "land rover" "land rover" "land rover" "lincoln"    "lincoln"   
[137] "lincoln"    "mercury"    "mercury"    "mercury"    "mercury"    "nissan"     "nissan"     "nissan"    
[145] "nissan"     "nissan"     "nissan"     "nissan"     "nissan"     "nissan"     "nissan"     "nissan"    
[153] "nissan"     "nissan"     "pontiac"    "pontiac"    "pontiac"    "pontiac"    "pontiac"    "subaru"    
[161] "subaru"     "subaru"     "subaru"     "subaru"     "subaru"     "subaru"     "subaru"     "subaru"    
[169] "subaru"     "subaru"     "subaru"     "subaru"     "subaru"     "toyota"     "toyota"     "toyota"    
[177] "toyota"     "toyota"     "toyota"     "toyota"     "toyota"     "toyota"     "toyota"     "toyota"    
[185] "toyota"     "toyota"     "toyota"     "toyota"     "toyota"     "toyota"     "toyota"     "toyota"    
[193] "toyota"     "toyota"     "toyota"     "toyota"     "toyota"     "toyota"     "toyota"     "toyota"    
[201] "toyota"     "toyota"     "toyota"     "toyota"     "toyota"     "toyota"     "toyota"     "volkswagen"
[209] "volkswagen" "volkswagen" "volkswagen" "volkswagen" "volkswagen" "volkswagen" "volkswagen" "volkswagen"
[217] "volkswagen" "volkswagen" "volkswagen" "volkswagen" "volkswagen" "volkswagen" "volkswagen" "volkswagen"
[225] "volkswagen" "volkswagen" "volkswagen" "volkswagen" "volkswagen" "volkswagen" "volkswagen" "volkswagen"
[233] "volkswagen" "volkswagen"

Packages

Whilst a lot of the functions you will need are in the base code that is active by default, you will at times need extra packages of code to do more powerful things. A commonly used package is ggplot2 [https://ggplot2.tidyverse.org/], which allows you to make beautiful figures in R. To use ggplot2 use need to install it and then load it from the library

if(!require(ggplot2)){install.packages("ggplot2")}
library(ggplot2)

Now that you have a package for making beautiful plots, less learn about “intelligent copy and paste” to make use of it.

Intelligent copy and paste

People experienced with coding do not write all their code from memory. They often copy and paste code from the internet and/or from their old scripts. So, assuming you’ve installed and loaded ggplot2 as described above, lets copy and paste code from their website (as of September 2022; https://ggplot2.tidyverse.org/)

ggplot(mpg, aes(displ, hwy, colour = class)) + 
  geom_point()

Good news is that we have a nice looking figure. But now we need to work out how to understand the code we’ve copied so that you can apply it to your own scripts. There’s a lot to unpack, so making the code more vertical can help you break it down and comment it out. Using the below and a description of the mpg dataframe (https://ggplot2.tidyverse.org/reference/mpg.html), can you comment it out

ggplot(
  mpg,              #
  aes(              #
    displ,          #
    hwy,            #
    colour = class  #
  )
) + 
geom_point()        #

Here’s how I would comment it out:

ggplot(
  mpg,              # dataframe
  aes(              # aesthetic properties
    displ,          # x-axis
    hwy,            # y-axis
    colour = class  # which column I will base the color on (often "color" is safer spelling in code)
  )
) + 
geom_point()        # what I would like drawn on

Now to understand the above code, try running it after changing lines. For example, what happens if you change the x-axis:

ggplot(
  mpg,              # dataframe
  aes(              # aesthetic properties
    cty,            # x-axis - updated
    hwy,            # y-axis
    colour = class  # which column I will base the color on (often "color" is safer spelling in code)
  )
) + 
geom_point()        # what I would like drawn on

To make beautiful figures in R, you can largely google the type of plot you want, copy the example code that the website has, and then swap in the relevant features for your plot. This principle of copying and pasting code, (making it vertical to make it legible is not necessary, but can be helpful), and then editing it to work for your own script is an essential skill to speed up your coding.

LS0tCnRpdGxlOiAiUiBiYXNpY3MiCm91dHB1dDogaHRtbF9ub3RlYm9vawotLS0KCiMjIFVzaW5nIHRoZSBjb25zb2xlIHZzLiBTY3JpcHRzIHZzLiBNYXJrZG93biB2cy4gUiBOb3RlYm9va3MKCldlbGNvbWUgdG8gdXNpbmcgUi4gVGhpcyBzdWJzZWN0aW9uIHdpbGwgZXhwbGFpbiB0aGUgYmFzaWNzIGFib3V0IFIuIEZpcnN0LCBsZXRzIGRpc2N1c3MgdGhlIGRpZmZlcmVudCB3YXlzIHRvIHdyaXRlIFIgY29kZSwgYXMgdGhlcmUgYXJlIChhdCBsZWFzdCkgNToKCi0gdHlwZSBpdCBkaXJlY3RseSBpbnRvIHRoZSBjb25zb2xlIChnZW5lcmFsbHkgbm90IHJlY29tbWVuZGVkKQotIHNhdmUgaXQgYXMgYSBzY3JpcHQgKGJldHRlcikgKioqbm90ZSB0aGF0IHNjcmlwdCBjYW4gcmVmZXIgdG8gYW55IG9mIHRoZSBiZWxvdywgYnV0IGluIHRoaXMgY2FzZSBpcyBiZWluZyB1c2VkIHRvIGRlc2NyaWJlIGEgc2NyaXB0IHRoYXQgZG9lc24ndCBnZW5lcmF0ZSBhIG5vdGVib29rKioqCi0gc2F2ZSBpdCBhcyBhbiBSIE1hcmtkb3duIChiZXR0ZXIgc3RpbGwpIC0gdGhpcyBhbGxvd3MgeW91IHRvIG1ha2UgYmVhdXRpZnVsIGRvY3VtZW50cwotIHNhdmUgaXQgYXMgYW4gUiBOb3RlYm9vayAoYXJndWFibHkgYmV0dGVyIHRoYW4gUiBNYXJrZG93bikgLSB0aGlzIGFsbG93cyB5b3UgdG8gbWFrZSBiZWF1dGlmdWwgZG9jdW1lbnRzLCBhbmQgaXMgcXVpY2tlcgoKCiMjIyBUaGUgQ29uc29sZQoKQXQgdGhlIGJvdHRvbSBsZWZ0IG9mIFJTdHVkaW8geW91IHNob3VsZCBoYXZlIGEgY29uc29sZSB0aGF0IGxvb2tzIHNvbWV0aGluZyBsaWtlIHdoYXQncyBoaWdobGlnaHRlZCBpbiA8c3BhbiBzdHlsZT0iY29sb3I6cmVkIj5yZWQ8L3NwYW4+IGJlbG93OgoKPGltZyBzcmM9InJCYXNpY3MvY29uc29sZS5wbmciPgoKWW91IGNhbiB0eXBlIHN0cmFpZ2h0IGludG8gdGhlIGNvbnNvbGUsIHRvIGdldCBhIHJlc3VsdC4gWW91IGNhbiBzY3JvbGwgdGhyb3VnaCB5b3VyIHByZXZpb3VzIGNvbW1hbmRzIGJ5IHByZXNzaW5nIHRoZSB1cCBhcnJvdyBpbiB0aGUgY29uc29sZS4gRWFjaCB0aW1lIGNvZGUgaXMgcnVuIGluIHRoZSBjb25zb2xlIGl0IHVwZGF0ZXMgdGhlIGVudmlyb25tZW50IGluIHRoZSB0b3AgcmlnaHQgb2YgUi1TdHVkaW86Cgo8aW1nIHNyYz0ickJhc2ljcy9lbnZpcm9ubWVudC5wbmciLz4KCiMjIyBTY3JpcHRzCgpUaGUgd29yZCAic2NyaXB0IiBjYW4gYmUgaW50ZXJwcmV0ZWQgc3BlY2lmaWNhbGx5LCB0byByZWZlciB0byBhIHR5cGUgb2YgUiBmaWxlIHRoYXQgaW5jbHVkZXMgYSBsb3Qgb2YgY29kZSwgb3IgZ2VuZXJhbGx5IHRvIHJlZmVyIHRvIGFueSBmaWxlIHRoYXQgaW5jbHVkZXMgYm90aCBSIGNvZGUgYW5kIGNvZGUgdGhhdCBhbGxvd3MgeW91IG1ha2UgYSBuaWNlIGxvb2tpbmcgcmVwb3J0LiBJbiB0aGlzIHN1YnNlY3Rpb24sIHdlIHdpbGwgYmUgZm9jdXNpbmcgb24gInNjcmlwdCIgYXMgYSBwYXJ0aWN1bGFyIHR5cGUgb2YgZmlsZS4gVG8gY3JlYXRlIGEgc2NyaXB0LCBjbGljayBvbiAqKkZpbGUgLT4gTmV3IEZpbGUgLT4gUiBTY3JpcHQqKgoKPGltZyBzcmM9InJCYXNpY3MvbmV3U2NyaXB0LnBuZyIvPgoKWW91IHdpbGwgdGhlbiBiZSBzaG93biBhIGJsYW5rIHNjcmlwdCwgaW4gd2hpY2ggeW91IGNhbiB3cml0ZSBhIHNlcmllcyBvZiBmdW5jdGlvbnMsIGFuZCB0aGVuIHJ1biB0aGVtLiBUbyBydW4gdGhlIGxpbmVzIG9mIGNvZGUsIHNlbGVjdCBhIGxpbmUsIGFuZCB0aGVuIHByZXNzIENUUkwtRU5URVIsIG9yIGhpZ2hsaWdodCBhIGNodW5rIG9mIGNvZGUgYW5kIHRoZW4gcHJlc3MgQ1RSTC1FTlRFUi4gSW4gZWl0aGVyIGNhc2UsIHRoZSBjb2RlIHdpbGwgYmUgc2VudCB0byB0aGUgY29uc29sZSBhbmQgcnVuIHRoZXJlLiAKCkFuIGFkdmFudGFnZSBvZiBhIHNjcmlwdCBvdmVyIGp1c3QgdXNpbmcgdGhlIGNvbnNvbGUgaXMgdGhhdCB5b3UgY2FuIGFuYWx5c2UgeW91ciBkYXRhIGluIGJvdGggKnN0cnVjdHVyZWQgYW5kIGNvbXBsZXggd2F5cyogd2hpY2ggaXMgZGlmZmljdWx0IGlmIHlvdSBhcmUgdHlwaW5nIGNvZGUgZGlyZWN0bHkgaW50byB0aGUgY29uc29sZS4KCiMjIyBSIE1hcmtkb3duCgpBcyBoaWdobGlnaHRlZCBhYm92ZSwgUiBNYXJrZG93biBpcyBhIHR5cGUgb2YgInNjcmlwdCIgaW4gdGhlIGdlbmVyYWwgc2Vuc2Ugb2YgdGhlIHdvcmQsIGJ1dCBhbGxvd3MgeW91IHRvIGNyZWF0ZSBiZWF1dGlmdWwgLmh0bWwgbm90ZWJvb2tzICguaHRtbCBmaWxlcyBhcmUgd2hhdCBpbnRlcm5ldCBwYWdlcyBhcmUgYmFzZWQgb24pLiBZb3UgYXJlIGluIGZhY3QgcmVhZGluZyBhbiBleGFtcGxlIG9mIHdoYXQgY2FuIGJlIHByb2R1Y2VkIGJ5IFIgTWFya2Rvd24gKGFuZCBSIE5vdGVib29rcykuIFRvIG1ha2UgYW4gUiBNYXJrZG93biBmaWxlLCBjbGljayBvbiAqKkZpbGUgLT4gTmV3IEZpbGUgLT4gUiBNYXJrZG93bioqLiBZb3Ugd2lsbCBiZSBhc2tlZCBmb3IgYSB0aXRsZSwgYXV0aG9yIGFuZCB3aGF0IG91dHB1dCB5b3Ugd291bGQgbGlrZS4gSSB3b3VsZCBzdWdnZXN0ICJmaXJzdCBtYXJrZG93biIsIHlvdXIgbmFtZSBhbmQgImh0bWwiIGFzIHRoZSByZXNwZWN0aXZlIGFuc3dlcnMuIFlvdSBzaG91bGQgdGhlbiBzZWUgc29tZXRoaW5nIGxpa2U6Cgo8aW1nIHNyYz0ickJhc2ljcy9tYXJrZG93bi5wbmciLz4KCioqVGhlIGZvbGxvd2luZyBwb2ludHMgYXBwbHkgdG8gYm90aCBSIE1hcmtkb3duIGFuZCBSIE5vdGVib29rcyoqCgpJZiB5b3UgbG9vayBhYm92ZSwgeW91IG1heSBub3RpY2UgdGhhdCB0aGVyZSBhcmUgMiB0eXBlcyBvZiBjb2RlOiBNYXJrZG93biAodG8gd3JpdGUgYSBuaWNlIGxvb2tpbmcgcmVwb3J0KSBhbmQgUiAoaW4gZ3JleSBjaHVua3MpLiBJIHRoaW5rIHRoZXNlIGFyZSB3ZWxsIGV4cGxhaW5lZCBoZXJlOiBodHRwczovL3d3dy5yc3R1ZGlvLmNvbS93cC1jb250ZW50L3VwbG9hZHMvMjAxNS8wMi9ybWFya2Rvd24tY2hlYXRzaGVldC5wZGYgc28gSSdsbCBqdXN0IGV4cGxhaW4gdGhhdCBSIE1hcmtkb3ducyBydW4gYWxsIHRoZSBjb2RlIGluIHRoZSBjaHVua3MgZWFjaCB0aW1lIHRoZXkgZ2VuZXJhdGUgdGhlIG91dHB1dCBmaWxlIChlLmcuIGh0bWwgZmlsZSkuIFRoaXMgaXMgaW1wb3J0YW50IHRvIGtub3csIGJlY2F1c2UgUiBOb3RlYm9va3MgZG8gKipub3QqKiBkbyB0aGlzLgoKIyMjIFIgTm90ZWJvb2tzCgpSIE5vdGVib29rcyBjYW4gYmUgY3JlYXRlZCBieSBjbGlja2luZyBvbiAqKkZpbGUgLT4gTmV3IEZpbGUgLT4gUiBOb3RlYm9vayoqLiBUaGV5IGxvb2sgcXVpdGUgc2ltaWxhciB0byBSIE1hcmtkb3ducywgYnV0IGF1dG9tYXRpY2FsbHkgZ2VuZXJhdGUgdGhlIC5odG1sIG91dHB1dCAqKmVhY2ggdGltZSB5b3Ugc2F2ZSB0aGUgbm90ZWJvb2sqKi4gVGhlIG91dHB1dCBmaWxlIHdpbGwgYmUgYSAqKi5uYi5odG1sKiogZmlsZSBpbiB0aGUgc2FtZSBmb2xkZXIgYXMgeW91ciBub3RlYm9vay4gCgoqKipWZXJ5IGltcG9ydGFudGx5KioqIC0gdGhlICoubmIuaHRtbCogZmlsZSB3aWxsIGJlIGJ1aWx0IGJhc2VkIG9uIHdoYXQgaGFwcGVuZWQgdGhlIGxhc3QgdGltZSB5b3UgcnVuIGVhY2ggUiBjaHVuay4gSWYgeW91IG5ldmVyIHJhbiB0aGUgUiBDaHVuaywgdGhlbiB0aGUgbmIuaHRtbCBmaWxlIHdpbGwgbm90IHVzZSB0aGUgb3V0cHV0IGZyb20gdGhhdCBjaHVuay4gKipUaGlzIG1ha2VzIFIgTm90ZWJvb2tzIHF1aWNrZXIgdGhhbiBSIE1hcmtkb3ducywgYmVjYXVzZSB5b3UgZG9uJ3QgaGF2ZSB0byBnZW5lcmF0ZSB0aGUgb3V0cHV0IGZyb20gc2NyYXRjaCBlYWNoIHRpbWUsIGJ1dCB0aGVyZSBpcyBhIHJpc2sgb2YgeW91IGZvcmdldHRpbmcgdG8gcnVuIGEgY2h1bmsgYWZ0ZXIgY2hhbmdpbmcgaXQqKi4KCiMjIEZ1bmRhbWVudGFsJ3Mgb2YgUgoKUiBhbGxvd3MgeW91IHRvIGNvbXBsZXRlIGNhbGN1bGF0aW9ucywgc28gbGV0cyBzdGFydCB3aXRoIHRoYXQuIFR5cGUgaW50byB5b3VyIG1hcmtkb3duIG9yIHNjcmlwdAoKT2Z0ZW4sIHlvdSBjYW4gdXNlIFIgYXMgYSBjYWxjdWxhdG9yLCBmb3IgZXhhbXBsZToKYGBge3J9CjUgKyAyCmBgYAoKSXQncyBoZWxwZnVsIHRvIHN0b3JlIHRoZXNlIGNhbGN1bGF0aW9ucyBpbnRvICoqb2JqZWN0cyoqOgpgYGB7cn0KYSA8LSA1ICsgMiAgIyB0aGlzIGlzIGV4YWN0bHkgdGhlIHNhbWUgYXMgd3JpdGluZyBhID0gNSArIDIsIGJ1dCA8LSBpcyBlbmNvdXJhZ2VkIGluIFIgdG8gYXZvaWQgY29uZnVzaW9uIHdpdGggb3RoZXIgdXNlcyBvZiA9IChlLmcuID09IG9wZXJhdG9yIHdoZW4geW91IGFyZSBjb21wYXJpbmcgaWYgdHdvIHZhbHVlcyBhcmUgaWRlbnRpY2FsKQojIHRoaXMgIyBpcyBzdGFydGluZyBhIGNvbW1lbnQsIGNvZGUgdGhhdCB3aWxsIGJlIGlnbm9yZWQgYnV0IGFsbG93cyB5b3UgdG8gYW5ub3RhdGUgeW91ciB3b3JrCmEgIyB0byBzaG93IHdoYXQgdGhlIHZhbHVlIDcgaXMgbm93IHN0b3JlZCBpbiB0aGUgb2JqZWN0ICJhIgpgYGAKCgpUaGlzIG1lYW5zIHRoYXQgeW91IGNhbiBjb21wYXJlIG9iamVjdHMgdG8gZWFjaCBvdGhlciBsYXRlcgoKYGBge3J9CmIgPC0gMgpiIC0gYQpjIDwtIGItYQpjICMgdG8gc2hvdyB3aGF0IGMgaXMKYGBgCgpTb21lIGFkdmljZS9ydWxlcyBmb3IgKipPYmplY3RzKio6CgotIFlvdSBjYW5ub3QgaGF2ZSBhIHNwYWNlIGluIGFuIG9iamVjdCBuYW1lLiAibXkgb2JqZWN0IiB3b3VsZCBiZSBhbiBpbnZhbGlkIG9iamVjdCBuYW1lLgotIG9iamVjdCBuYW1lcyBhcmUgKioqY2FzZS1zZW5zaXRpdmUqKiosIHNvIGlmIHlvdXIgb2JqZWN0IGlzIGNhbGxlZCAiTXlPYmplY3QiIHlvdSBjYW5ub3QgcmVmZXIgdG8gaXQgYXMgIm15b2JqZWN0Ii4KLSAiLiIgYW5kICJfIiBhcmUgYWNjZXB0YWJsZSBjaGFyYWN0ZXJzIGluIHZhcmlhYmxlIG5hbWVzLgotIHlvdSBjYW4gb3ZlcndyaXRlIG9iamVjdHMgaW4gdGhlIHNhbWUgd2F5IHRoYXQgeW91IGRlZmluZSBhbiBvYmplY3QKCmBgYHtyfQp0aGlzX29iamVjdCA8LSA1CnRoaXNfb2JqZWN0ICMgdG8gc2hvdyB3aGF0IHRoZSBvYmplY3QgdmFsdWUgaXMKdGhpc19vYmplY3QgPC0gMTAgIyBvdmVyd3JpdGVzIHRoaXNfb2JqZWN0CnRoaXNfb2JqZWN0ICMgc2hvdWxkIG5vdyBzaG93IDEwCmBgYAoKLSBiZSBjYXJlZnVsIHRvIG5vdCBnaXZlIGFuIG9iamVjdCB0aGUgc2FtZSBuYW1lIGFzIGEgZnVuY3Rpb24hIFRoaXMgd2lsbCBvdmVyd3JpdGUgdGhlIGZ1bmN0aW9uLiBUbyBjaGVjayBpZiB0aGUgbmFtZSBhbHJlYWR5IGV4aXN0cywgeW91IGNhbiBzdGFydCB0eXBpbmcgaXQgYW5kIHByZXNzIHRhYi4gU28gdHlwaW5nICJ0LnRlIiBhbmQgcHJlc3NpbmcgdGhlIHRhYiB3aWxsIGdpdmUgeW91ICJ0LnRlc3QiCgoKIyMjIEZ1bmN0aW9ucwoKSW4gYSB2YXJpZXR5IG9mIGNvZGluZyBsYW5ndWFnZXMgbGlrZSBSLCAqKmZ1bmN0aW9ucyoqIGFyZSBsaW5lcyBvZiBjb2RlIHlvdSBjYW4gYXBwbHkgZWFjaCB0aW1lIHlvdSBjYWxsIHRoZSBmdW5jdGlvbiwgYW5kIGFwcGx5IGl0IHRvICoqaW5wdXQqKiB0byBnZXQgYW4gKipvdXRwdXQqKi4gSWYgeW91IHdhbnRlZCB0byBtYWtlIGEgZnVuY3Rpb24gdGhhdCBtdWx0aXBsaWVkIG51bWJlcnMgYnkgMiwgaXQgd291bGQgbG9vayBzb21ldGhpbmcgbGlrZToKCmBgYHtyfQp0aW1lc190d28gPC0gZnVuY3Rpb24oaW5wdXQpeyAgIyBEZWZpbmUgeW91ciBmdW5jdGlvbiBieSBzdGF0aW5nIGl0J3MgbmFtZSwgYW5kIHRoZW4gdXNpbmcgPC0gdG8gZGVzY3JpYmUgaXQKICBvdXRwdXQgPSBpbnB1dCAqIDIgICAgICAgICAgICMgY3JlYXRlcyBhbiBvdXRwdXQgb2JqZWN0IHRoYXQgaXMgdGhlIGlucHV0IG9iamVjdCAoc2VlIGxpbmUgYWJvdmUpIHggMgogIHJldHVybiAob3V0cHV0KSAgICAgICAgICAgICAgIyBnaXZlcyB0aGUgb3V0cHV0IGJhY2sgdG8gdGhlIHVzZXIgd2hlbiB0aGV5IHJ1biB0aGUgZnVuY3Rpb24KfQp0aW1lc190d28oNCkgICAgICAgICAgICAgICAgICAgIyBzaG91bGQgZ2l2ZSB5b3UgOApgYGAKClRoZSAqKmdyZWF0IG5ld3MqKiBpcyB0aGF0IHlvdSBkb24ndCBuZWVkIHRvIHdyaXRlIGZ1bmN0aW9ucyA5OSUgb2YgdGhlIHRpbWUgaW4gUiwgdGhlcmUgYXJlIGEgd2lkZSB2YXJpZXR5IG9mIGZ1bmN0aW9ucyB0aGF0IGFyZSBhdmFpbGFibGUuIFNvbWUgb2Ygd2hpY2ggd2lsbCBiZSB1c2VkIGluIHRoZSBuZXh0IHNlY3Rpb24uCgojIyMgVHlwZXMgb2YgT2JqZWN0cwoKIyMjIyBWZWN0b3JzCgoqKlZlY3RvcnMqKiBzdG9yZSBhIHNlcmllcyBvZiB2YWx1ZXMuIE9mdGVuIHRoZXNlIHdpbGwgYmUgYSBzZXJpZXMgb2YgbnVtYmVyczoKCmBgYHtyfQpudW1lcmljX3ZlY3RvciA9IGMoMSwyLDMpCm51bWVyaWNfdmVjdG9yCmBgYAoKVGhlICJjIiBhYm92ZSBpcyBzaG9ydCBmb3IgImNvbWJpbmUiIGFzIHlvdSdyZSBjb21iaW5pbmcgdmFsdWVzIHRvZ2V0aGVyIHRvIG1ha2UgdGhpcyB2ZWN0b3IuIAoqKlN0cmluZ3MqKiBhcmUgdmFsdWVzIHRoYXQgaGF2ZSBjaGFyYWN0ZXJzIChhbHNvIGtub3duIGFzIGxldHRlcnMpIGluIHRoZW0uIExldHMgc2VlIGlmIHdlIGNhbiBtYWtlIGEgdmVjdG9yIG9mICoqc3RyaW5ncyoqOgoKYGBge3J9CnN0cmluZ192ZWN0b3IgPSBjKCJhIiwgImIiLCAiYyIpCnN0cmluZ192ZWN0b3IKYGBgCgpMb29rcyBsaWtlIHdlIGNhbi4gQnV0IHdoYXQgaGFwcGVucyBpZiB5b3UgbWl4IHN0cmluZ3MgYW5kIG51bWJlcnMgaW4gYSAqKnZlY3RvcioqOgoKYGBge3J9Cm1peGVkX3ZlY3RvciA9IGMoImEiLCAxLCAiYyIpCm1peGVkX3ZlY3RvcgpgYGAKClIgc2VlbXMgdG8gYmUgaGFwcHkgdG8gcHV0IHRoZW0gaW50byBhIHNpbmdsZSB2ZWN0b3IuIEJ1dCB0aGVyZSBhcmUgZGlmZmVyZW50IHR5cGVzIG9mIHZhbHVlcyBhbmQgdmVjdG9ycywgc28gbGV0cyBhc2sgUiB3aGF0IGVhY2ggdHlwZSBvZiAodXNpbmcgdGhlICJ0eXBlb2YiICoqZnVuY3Rpb24qKikgdmVjdG9ycyB3ZSBoYXZlIGFib3ZlOgoKYGBge3J9CnR5cGVvZihudW1lcmljX3ZlY3RvcikKdHlwZW9mKHN0cmluZ192ZWN0b3IpCnR5cGVvZihtaXhlZF92ZWN0b3IpCmBgYAoKVGhlIG51bWVyaWMgdmVjdG9yIGlzIGEgImRvdWJsZSIgdmVjdG9yLiAqKkRvdWJsZSoqIHJlZmVycyB0byB0aGUgZmFjdCB0aGF0IHRoZSBudW1iZXJzICpjYW4gaW5jbHVkZSBkZWNpbWFscyosIGFzIG9wcG9zZWQgdG8gKippbnRlZ2VyKiogbnVtYmVycyAqd2hpY2ggaGF2ZSB0byBiZSB3aG9sZSBudW1iZXJzKi4gSW50ZXJlc3RpbmdseSwgUiBoYXMgYXNzdW1lZCB0aGUgbGlzdCBvZiBudW1iZXJzIHNob3VsZCBiZSAqKmRvdWJsZSoqIHJhdGhlciB0aGFuICoqaW50ZWdlcioqLCB3aGljaCBzZWVtcyBsaWtlIHRoZSBtb3JlIHJvYnVzdCB0aGluZyB0byBkbywgYXMgaW50ZWdlciBudW1iZXJzIGNhbiBhbHdheXMgYmUgZG91YmxlLCBidXQgZG91YmxlIG51bWJlcnMgY2FuJ3QgYWx3YXlzIGJlIGludGVnZXJzLgoKIyMjIyBEYXRhIGZyYW1lcwoKKipEYXRhIGZyYW1lcyoqIGxvb2sgbGlrZSB0YWJsZXMsIGluIHdoaWNoIHlvdSBoYXZlIGEgc2VyaWVzIG9mIGNvbHVtbnMgd2l0aCAqKmhlYWRlcnMqKiB0aGF0IGRlc2NyaWJlIGVhY2ggY29sdW1uLiAKClNvbWUgZGF0YSBmcmFtZXMgYXJlIGFscmVhZHkgbG9hZGVkIGludG8gUlN0dWRpbyB3aGVuIHlvdSBydW4gaXQsIHN1Y2ggYXMgdGhlICJtcGciIGRhdGFmcmFtZS4gVG8gbG9vayBhdCBpdCwganVzdCB0eXBlIGluIGl0J3MgbmFtZToKCmBgYHtyfQptcGcKYGBgCjxpbWcgc3JjPSJyQmFzaWNzL21wZ1RhYmxlLnBuZyIvPgoqTm90ZSB0aGF0IHlvdSBtYXkgc2VlIDIgdGFibGVzIGFib3ZlLCBidXQgdGhleSBzaG91bGQgYmUgaWRlbnRpY2FsIGlmIHNvKgoKVGhlICoqbXBnKiogZGF0YWZyYW1lIGhhcyBpbmZvcm1hdGlvbiBhYm91dCBhIHZhcmlldHkgb2YgY2FycywgdGhlaXIgbWFudWZhY3R1cmVycywgbW9kZWxzLCBhcyBkZXNjcmliZWQgaHR0cHM6Ly9nZ3Bsb3QyLnRpZHl2ZXJzZS5vcmcvcmVmZXJlbmNlL21wZy5odG1sLiBZb3Ugd2lsbCBuZWVkIHRvIHJlZmVyIHRvIGRhdGEgZnJhbWVzIGFuZCB0aGVpciBjb2x1bW5zLCB0aGUgY29udmVudGlvbiBmb3IgdGhpcyBiZWluZyB0byB3cml0ZSBkYXRhIGZyYW1lJGNvbHVtbi4gTGV0cyBkbyB0aGlzIHRvIHNlZSB3aGF0J3MgaW4gdGhlICJtYW51ZmFjdHVyZXIiIGNvbHVtbjoKCmBgYHtyfQptcGckbWFudWZhY3R1cmVyCmBgYAoKCiMjIyBQYWNrYWdlcwoKV2hpbHN0IGEgbG90IG9mIHRoZSBmdW5jdGlvbnMgeW91IHdpbGwgbmVlZCBhcmUgaW4gdGhlICpiYXNlKiBjb2RlIHRoYXQgaXMgYWN0aXZlIGJ5IGRlZmF1bHQsIHlvdSB3aWxsIGF0IHRpbWVzIG5lZWQgZXh0cmEgcGFja2FnZXMgb2YgY29kZSB0byBkbyBtb3JlIHBvd2VyZnVsIHRoaW5ncy4gQSBjb21tb25seSB1c2VkIHBhY2thZ2UgaXMgZ2dwbG90MiBbaHR0cHM6Ly9nZ3Bsb3QyLnRpZHl2ZXJzZS5vcmcvXSwgd2hpY2ggYWxsb3dzIHlvdSB0byBtYWtlICoqKmJlYXV0aWZ1bCoqKiBmaWd1cmVzIGluIFIuIFRvIHVzZSBnZ3Bsb3QyIHVzZSBuZWVkIHRvICoqaW5zdGFsbCoqIGl0IGFuZCB0aGVuIGxvYWQgaXQgZnJvbSB0aGUgKipsaWJyYXJ5KioKCmBgYHtyfQppZighcmVxdWlyZShnZ3Bsb3QyKSl7aW5zdGFsbC5wYWNrYWdlcygiZ2dwbG90MiIpfQpsaWJyYXJ5KGdncGxvdDIpCmBgYAoKTm93IHRoYXQgeW91IGhhdmUgYSBwYWNrYWdlIGZvciBtYWtpbmcgYmVhdXRpZnVsIHBsb3RzLCBsZXNzIGxlYXJuIGFib3V0ICJpbnRlbGxpZ2VudCBjb3B5IGFuZCBwYXN0ZSIgdG8gbWFrZSB1c2Ugb2YgaXQuCgojIyMgSW50ZWxsaWdlbnQgY29weSBhbmQgcGFzdGUKClBlb3BsZSBleHBlcmllbmNlZCB3aXRoIGNvZGluZyAqKipkbyBub3Qgd3JpdGUgYWxsIHRoZWlyIGNvZGUgZnJvbSBtZW1vcnkqKiouIFRoZXkgb2Z0ZW4gY29weSBhbmQgcGFzdGUgY29kZSBmcm9tIHRoZSBpbnRlcm5ldCBhbmQvb3IgZnJvbSB0aGVpciBvbGQgc2NyaXB0cy4gU28sIGFzc3VtaW5nIHlvdSd2ZSBpbnN0YWxsZWQgYW5kIGxvYWRlZCBnZ3Bsb3QyIGFzIGRlc2NyaWJlZCBhYm92ZSwgbGV0cyBjb3B5IGFuZCBwYXN0ZSBjb2RlIGZyb20gdGhlaXIgd2Vic2l0ZSAoYXMgb2YgU2VwdGVtYmVyIDIwMjI7IGh0dHBzOi8vZ2dwbG90Mi50aWR5dmVyc2Uub3JnLykKCmBgYHtyfQpnZ3Bsb3QobXBnLCBhZXMoZGlzcGwsIGh3eSwgY29sb3VyID0gY2xhc3MpKSArIAogIGdlb21fcG9pbnQoKQpgYGAKR29vZCBuZXdzIGlzIHRoYXQgd2UgaGF2ZSBhIG5pY2UgbG9va2luZyBmaWd1cmUuIEJ1dCBub3cgd2UgbmVlZCB0byB3b3JrIG91dCBob3cgdG8gdW5kZXJzdGFuZCB0aGUgY29kZSB3ZSd2ZSBjb3BpZWQgc28gdGhhdCB5b3UgY2FuIGFwcGx5IGl0IHRvIHlvdXIgb3duIHNjcmlwdHMuIFRoZXJlJ3MgYSBsb3QgdG8gdW5wYWNrLCBzbyBtYWtpbmcgdGhlIGNvZGUgbW9yZSAqKnZlcnRpY2FsKiogY2FuIGhlbHAgeW91IGJyZWFrIGl0IGRvd24gYW5kIGNvbW1lbnQgaXQgb3V0LiBVc2luZyB0aGUgYmVsb3cgYW5kIGEgZGVzY3JpcHRpb24gb2YgdGhlIG1wZyBkYXRhZnJhbWUgKGh0dHBzOi8vZ2dwbG90Mi50aWR5dmVyc2Uub3JnL3JlZmVyZW5jZS9tcGcuaHRtbCksIGNhbiB5b3UgY29tbWVudCBpdCBvdXQKCmBgYHtyfQpnZ3Bsb3QoCiAgbXBnLCAgICAgICAgICAgICAgIwogIGFlcyggICAgICAgICAgICAgICMKICAgIGRpc3BsLCAgICAgICAgICAjCiAgICBod3ksICAgICAgICAgICAgIwogICAgY29sb3VyID0gY2xhc3MgICMKICApCikgKyAKZ2VvbV9wb2ludCgpICAgICAgICAjCmBgYApIZXJlJ3MgaG93IEkgd291bGQgY29tbWVudCBpdCBvdXQ6CgpgYGB7cn0KZ2dwbG90KAogIG1wZywgICAgICAgICAgICAgICMgZGF0YWZyYW1lCiAgYWVzKCAgICAgICAgICAgICAgIyBhZXN0aGV0aWMgcHJvcGVydGllcwogICAgZGlzcGwsICAgICAgICAgICMgeC1heGlzCiAgICBod3ksICAgICAgICAgICAgIyB5LWF4aXMKICAgIGNvbG91ciA9IGNsYXNzICAjIHdoaWNoIGNvbHVtbiBJIHdpbGwgYmFzZSB0aGUgY29sb3Igb24gKG9mdGVuICJjb2xvciIgaXMgc2FmZXIgc3BlbGxpbmcgaW4gY29kZSkKICApCikgKyAKZ2VvbV9wb2ludCgpICAgICAgICAjIHdoYXQgSSB3b3VsZCBsaWtlIGRyYXduIG9uCmBgYAoKTm93IHRvIHVuZGVyc3RhbmQgdGhlIGFib3ZlIGNvZGUsIHRyeSBydW5uaW5nIGl0IGFmdGVyIGNoYW5naW5nIGxpbmVzLiBGb3IgZXhhbXBsZSwgd2hhdCBoYXBwZW5zIGlmIHlvdSBjaGFuZ2UgdGhlIHgtYXhpczoKCmBgYHtyfQpnZ3Bsb3QoCiAgbXBnLCAgICAgICAgICAgICAgIyBkYXRhZnJhbWUKICBhZXMoICAgICAgICAgICAgICAjIGFlc3RoZXRpYyBwcm9wZXJ0aWVzCiAgICBjdHksICAgICAgICAgICAgIyB4LWF4aXMgLSB1cGRhdGVkCiAgICBod3ksICAgICAgICAgICAgIyB5LWF4aXMKICAgIGNvbG91ciA9IGNsYXNzICAjIHdoaWNoIGNvbHVtbiBJIHdpbGwgYmFzZSB0aGUgY29sb3Igb24gKG9mdGVuICJjb2xvciIgaXMgc2FmZXIgc3BlbGxpbmcgaW4gY29kZSkKICApCikgKyAKZ2VvbV9wb2ludCgpICAgICAgICAjIHdoYXQgSSB3b3VsZCBsaWtlIGRyYXduIG9uCgpgYGAKVG8gbWFrZSBiZWF1dGlmdWwgZmlndXJlcyBpbiBSLCB5b3UgY2FuIGxhcmdlbHkgZ29vZ2xlIHRoZSB0eXBlIG9mIHBsb3QgeW91IHdhbnQsIGNvcHkgdGhlIGV4YW1wbGUgY29kZSB0aGF0IHRoZSB3ZWJzaXRlIGhhcywgYW5kIHRoZW4gc3dhcCBpbiB0aGUgcmVsZXZhbnQgZmVhdHVyZXMgZm9yIHlvdXIgcGxvdC4gVGhpcyBwcmluY2lwbGUgb2YgY29weWluZyBhbmQgcGFzdGluZyBjb2RlLCAobWFraW5nIGl0IHZlcnRpY2FsIHRvIG1ha2UgaXQgbGVnaWJsZSBpcyBub3QgbmVjZXNzYXJ5LCBidXQgY2FuIGJlIGhlbHBmdWwpLCBhbmQgdGhlbiBlZGl0aW5nIGl0IHRvIHdvcmsgZm9yIHlvdXIgb3duIHNjcmlwdCBpcyBhbiAqKmVzc2VudGlhbCBza2lsbCoqIHRvIHNwZWVkIHVwIHlvdXIgY29kaW5nLg==